package com.example.sknetwork

import android.util.Log
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import okhttp3.*
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.lang.StringBuilder
import java.util.concurrent.TimeUnit

import okio.Buffer
import java.lang.Exception
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets.UTF_8


object ApiFactory {

    private val apiTag = "ApiFactory";

    /**
     * 创建日志拦截器
     * */
    private val mLogInterceptor: Interceptor by lazy {
        LoggingInterceptor()
    }

    /**
     * retrofit 单例模式
     * */
    private val retrofit: Retrofit by lazy {
        val builder = Retrofit.Builder().run {
            client(mClient)
            baseUrl(baseUrl)
            addCallAdapterFactory(CoroutineCallAdapterFactory())
            addConverterFactory(GsonConverterFactory.create())
            this
        }
        builder.build()
    }

    //okhttp 客户端
    private lateinit var mClient: OkHttpClient

    //baseUrl 地址
    private lateinit var baseUrl: String

    /**
     * 构造接口实例
     * */
    fun <T> create(clazz: Class<T>): T = retrofit.create(clazz)

    /**
     * 创建接口实例
     * */
    fun <T> create(baseUrl: String, clazz: Class<T>): T {
        return Retrofit.Builder().baseUrl(baseUrl).client(
            mClient
        ).addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(CoroutineCallAdapterFactory()).build().create(clazz)
    }

    /**
     * 日志拦截器
     * */
    private class LoggingInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val builder = StringBuilder();
            val time = System.nanoTime();
            val response: Response = with(chain.request()) {
                builder.append("$method\n")
                builder.append("Sending request \n $url")
                if (method == "POST") {
                    builder.append("?")
                    when (val body = body) {
                        is FormBody -> {
                            for (j in 0 until body.size) {
                                builder.append("${body.name(j)} = ${body.value(j)}")
                                if (j != body.size - 1) {
                                    builder.append("&")
                                }
                            }
                        }
                    }
                }
                builder.append("\n").append(headers)
                chain.proceed(this)
            }
            builder.append("Received res in ${(System.nanoTime() - time) / 1e6} ms")
            builder.append("code is ${response.code} \n")
            val responseBody = response.body
            val contentLength = responseBody!!.contentLength()
            val source = responseBody!!.source()
            try {
                source.request(Long.MAX_VALUE) // Buffer the entire body.
            } catch (e: IOException) {
                e.printStackTrace()
            }
            try {
                val buffer: Buffer = source.buffer()
                var charset: Charset? = UTF_8
                val contentType: MediaType? = responseBody.contentType()
                if (contentType != null) {
                    charset = contentType.charset()
                }
                if (contentLength != 0L) {
                    val result: String = buffer.clone().readString(charset!!)
                    builder.append("result is $result \n")

                }
            } catch (e: Exception) {

            }

            Log.i(apiTag, builder.toString())
            return response
        }

    }
}